// server.js

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const path = require('path');

// --- 1. 导入游戏模块 ---
// 使用 require() 来加载我们刚刚创建的游戏文件
const CardGame = require('./games/cardGame');
const TicTacToe = require('./games/ticTacToe');
const Geistes = require('./games/geistes');
const LoveLetter = require('./games/loveletter');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"]
  }
});

// --- 1. 配置静态文件服务 ---
// 告诉 Express，所有静态文件都在 'public' 目录下
app.use(express.static('public'));

// --- 2. 配置路由 ---
// 兜底路由：所有其他请求都返回主页面 index.html
// 注意：这个中间件必须放在所有其他路由的最后！
app.use((req, res) => {
  // 使用 sendFile 发送文件时，必须提供文件的绝对路径
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});


// --- 2. 创建游戏逻辑分发器 ---
// 现在这个对象变得非常简洁，它只是一个模块的映射
const gameHandlers = {
  card_game: CardGame,
  tic_tac_toe: TicTacToe,
  geistes: Geistes,
  loveletter: LoveLetter
  // 未来添加新游戏，只需在这里添加一行映射即可！
  // snake: require('./games/snakeGame')
};

// ... (rooms 对象和其他 setup 保持不变) ...
const rooms = {};

io.on('connection', (socket) => {
  console.log(`玩家 ${socket.id} 已连接`);

  socket.on('create_room', (roomData) => {
    const { roomId, playerName } = roomData;

    // 检查房间是否已存在
    if (rooms[roomId]) {
      socket.emit('room_creation_result', { success: false, message: '房间ID已存在！' });
      return;
    }

    // 创建房间并加入
    socket.join(roomId);
    rooms[roomId] = {
       id: roomId,
      players: [{ id: socket.id, name: playerName }],
      hostId: socket.id, // 房主ID（创建房间的玩家）
      // 其他游戏状态，如牌堆、当前回合等
    };

    console.log(`玩家 ${playerName} 创建了房间 ${roomId}`);
    
    // 通知创建者成功（创建者自动是房主）
    socket.emit('room_creation_result', { 
      success: true, 
      message: '房间创建成功！', 
      roomId: roomId,
      hostId: socket.id,
      hostName: playerName,
      isHost: true
    });
    // 可以广播房间列表更新给所有人（如果需要）
    // io.emit('room_list_updated', Object.keys(rooms));
  });

  socket.on('join_room', (roomData) => {
    const { roomId, playerName } = roomData;
    const room = rooms[roomId];

    // 检查房间是否存在
    if (!room) {
      socket.emit('join_result', { success: false, message: '房间不存在！' });
      return;
    }

    // TODO： 后续可设置房间最大人数
    // 检查房间是否已满
    if (room.players.length >= 5) {
      socket.emit('join_result', { success: false, message: '房间已满！' });
      return;
    }

    // 加入房间
    socket.join(roomId);
    room.players.push({ id: socket.id, name: playerName });
    
    console.log(`玩家 ${playerName} 加入了房间 ${roomId}`);

    // 获取房主信息
    const host = room.players.find(p => p.id === room.hostId);
    const isHost = room.hostId === socket.id;
    
    // 通知自己加入成功
    socket.emit('join_result', { 
      success: true, 
      message: '加入房间成功！', 
      roomId: roomId,
      hostId: room.hostId,
      hostName: host ? host.name : '',
      isHost: isHost
    });
    
    // 通知房间内的所有玩家（包括自己），有新玩家加入，并可以开始游戏
    // 需要为每个玩家单独计算 isHost
    room.players.forEach(player => {
      const playerSocket = io.sockets.sockets.get(player.id);
      if (playerSocket) {
        const isHost = room.hostId === player.id;
        playerSocket.emit('player_joined', { 
          players: room.players,
          message: `玩家 ${playerName} 已加入房间，游戏可以开始了！`,
          isGameStarted: room.currentGame && !(room.gameState && room.gameState.isGameEnded),
          hostId: room.hostId,
          hostName: host ? host.name : '',
          isHost: isHost
        });
      }
    });
  });

  socket.on('request_players', ({ roomId }) => {
    console.log('request_players:',roomId);
    if (rooms[roomId]) {
        const room = rooms[roomId];
        // 检查游戏是否已结束
        const isGameEnded = room.gameState && room.gameState.isGameEnded;
        
        // 获取房主信息
        const host = room.players.find(p => p.id === room.hostId);
        const isHost = room.hostId === socket.id;
        
        // 直接将该房间的玩家列表发送给请求的客户端
        socket.emit('update_players', {
            players: room.players,
            isGameStarted: room.currentGame && !isGameEnded, // 游戏已结束时不再显示为进行中
            hostId: room.hostId,
            hostName: host ? host.name : '',
            isHost: isHost
        });
    }
  });

  // 随机查找并加入有空位的房间
  socket.on('random_join_room', (data) => {
    const { playerName } = data;
    console.log(`玩家 ${playerName} 请求随机加入房间`);

    // 查找所有有空位的房间（玩家数小于5，且游戏未开始或已结束）
    const availableRooms = [];
    for (const roomId in rooms) {
      const room = rooms[roomId];
      const isGameEnded = room.gameState && room.gameState.isGameEnded;
      const canJoin = room.players.length < 5 && (!room.currentGame || isGameEnded);
      
      if (canJoin) {
        availableRooms.push(roomId);
      }
    }

    // 如果没有可用的房间
    if (availableRooms.length === 0) {
      socket.emit('random_join_result', { 
        success: false, 
        message: '当前没有合适的房间' 
      });
      return;
    }

    // 随机选择一个房间
    const randomRoomId = availableRooms[Math.floor(Math.random() * availableRooms.length)];
    const room = rooms[randomRoomId];

    // 加入房间
    socket.join(randomRoomId);
    room.players.push({ id: socket.id, name: playerName });
    
    console.log(`玩家 ${playerName} 随机加入了房间 ${randomRoomId}`);

    // 获取房主信息
    const host = room.players.find(p => p.id === room.hostId);
    const isHost = room.hostId === socket.id;
    
    // 通知自己加入成功
    socket.emit('random_join_result', { 
      success: true, 
      message: '加入房间成功！', 
      roomId: randomRoomId,
      hostId: room.hostId,
      hostName: host ? host.name : '',
      isHost: isHost
    });
    
    // 通知房间内的所有玩家（包括自己），有新玩家加入
    room.players.forEach(player => {
      const playerSocket = io.sockets.sockets.get(player.id);
      if (playerSocket) {
        const isHost = room.hostId === player.id;
        playerSocket.emit('player_joined', { 
          players: room.players,
          message: `玩家 ${playerName} 已加入房间，游戏可以开始了！`,
          isGameStarted: room.currentGame && !(room.gameState && room.gameState.isGameEnded),
          hostId: room.hostId,
          hostName: host ? host.name : '',
          isHost: isHost
        });
      }
    });
  });

  socket.on('start_game', (data) => {
    const { roomId, gameName } = data;
    const room = rooms[roomId];

    console.log("roomID:", roomId);
    console.log("gameName:", gameName);
    console.log("room exists:", !!room);
    console.log("socket in room:", socket.rooms.has(roomId));
    console.log("game handler exists:", !!gameHandlers[gameName]);
    console.log("available game handlers:", Object.keys(gameHandlers));

    if (!room || !socket.rooms.has(roomId) || !gameHandlers[gameName]) {
      console.error('无法开始游戏，条件不满足！', {
        room: !!room,
        socketInRoom: socket.rooms.has(roomId),
        gameHandler: !!gameHandlers[gameName]
      });
      return socket.emit('error', { message: '无法开始游戏，条件不满足！' });
    }

    // 检查是否是房主
    if (room.hostId !== socket.id) {
      console.error('只有房主才能开始游戏！', {
        hostId: room.hostId,
        socketId: socket.id
      });
      return socket.emit('error', { message: '只有房主才能开始游戏！' });
    }

    room.currentGame = gameName;
    console.log(`开始游戏: ${gameName} 在房间 ${roomId}`);
    
    try {
      // 调用对应游戏模块的 startGame 方法，并传入 room 和 io
      gameHandlers[gameName].startGame(room, io);
      console.log(`游戏 ${gameName} 启动成功`);
    } catch (error) {
      console.error(`启动游戏 ${gameName} 时出错:`, error);
      socket.emit('error', { message: `启动游戏失败: ${error.message}` });
    }
  });

  socket.on('game_action', (data) => {
    const { roomId, action, actionData } = data;
    const room = rooms[roomId];

    if (!room || !socket.rooms.has(roomId) || !room.currentGame) {
      return socket.emit('error', { message: '无法执行操作，条件不满足！' });
    }
    
    console.log("actionData:", actionData);

    const gameHandler = gameHandlers[room.currentGame];
    if (gameHandler) {
      // 调用对应游戏模块的 handleAction 方法
      gameHandler.handleAction(room, socket, io, { action, data: actionData });
    }
  });

  socket.on('leave_game', (data) => {
      const { roomId } = data;
      const room = rooms[roomId];

      if (!room || !socket.rooms.has(roomId)) {
         return socket.emit('error', { message: '无法退出游戏，没有找到所在房间！' });
       }

       socket.emit('game_left_success');
   });

  socket.on('rejoin_game',(data) => {
      const { roomId } = data;
      const room = rooms[roomId];

      if (!room || !socket.rooms.has(roomId)) {
         return socket.emit('error', { message: '无法返回游戏，没有找到所在房间！' });
       }

       const gameName = room.currentGame;
        gameHandlers[gameName].rejoinGame(room, io, socket.id);
  });

  socket.on('leave_room', (data) => {
        const { roomId } = data;
        const room = rooms[roomId];

        // 检查房间是否存在，以及玩家是否在这个房间里
        if (!room || !socket.rooms.has(roomId)) {
            console.log(`玩家 ${socket.id} 尝试离开一个不存在或不在其中的房间 ${roomId}`);
            return;
        }

        console.log(`玩家 ${socket.id} 请求离开房间 ${roomId}`);

        // 1. 从房间的 players 列表中找到并移除该玩家
        const playerIndex = room.players.findIndex(p => p.id === socket.id);
        if (playerIndex !== -1) {
            const playerName = room.players[playerIndex].name;
            const wasHost = room.hostId === socket.id; // 记录离开的玩家是否是房主
            room.players.splice(playerIndex, 1);
            
            // 2. 如果离开的玩家是房主，且房间中还有玩家，则转移房主权限
            let hostChanged = false;
            if (wasHost && room.players.length > 0) {
                // 选择第一个剩余的玩家作为新房主（原来的第二个玩家）
                room.hostId = room.players[0].id;
                hostChanged = true;
                console.log(`房主 ${playerName} 离开，房主权限已转移给 ${room.players[0].name}`);
            }
            
            // 获取房主信息
            const host = room.players.find(p => p.id === room.hostId);
            const isGameEnded = room.gameState && room.gameState.isGameEnded;
            
            // 3. 通知房间内剩余的玩家，有玩家离开了（为每个玩家单独发送isHost）
            room.players.forEach(player => {
              const playerSocket = io.sockets.sockets.get(player.id);
              if (playerSocket) {
                const isHost = room.hostId === player.id;
                const message = hostChanged 
                  ? `房主 ${playerName} 已离开房间，${host.name} 成为新房主。`
                  : `玩家 ${playerName} 已离开房间。`;
                playerSocket.emit('player_left', { 
                  players: room.players,
                  message: message,
                  isGameStarted: room.currentGame && !isGameEnded,
                  hostId: room.hostId,
                  hostName: host ? host.name : '',
                  isHost: isHost,
                  hostChanged: hostChanged // 标记房主是否变更
                });
              }
            });
            
            // 4. 将该玩家的 socket 从房间中移除
            socket.leave(roomId);

            // 5. 如果房间为空，则删除房间
            if (room.players.length === 0) {
                delete rooms[roomId];
                console.log(`房间 ${roomId} 已为空，已删除。`);
            }

            // 6. 向离开的玩家发送一个确认消息
            socket.emit('room_left_success');
            
            console.log(`玩家 ${playerName} 已成功离开房间 ${roomId}`);
        }
    });

  socket.on('disconnect', () => {
    console.log(`玩家 ${socket.id} 已断开连接`);

    // 遍历所有房间，找到玩家所在的房间并移除他
    for (const roomId in rooms) {
      const room = rooms[roomId];
      const playerIndex = room.players.findIndex(p => p.id === socket.id);
      
      if (playerIndex !== -1) {
        const playerName = room.players[playerIndex].name;
        const wasHost = room.hostId === socket.id; // 记录掉线的玩家是否是房主
        room.players.splice(playerIndex, 1);
        
        // 如果掉线的玩家是房主，且房间中还有玩家，则转移房主权限
        let hostChanged = false;
        if (wasHost && room.players.length > 0) {
          //直接把第一个剩余的玩家作为新房主
          room.hostId = room.players[0].id;
          hostChanged = true;
          console.log(`房主 ${playerName} 掉线，房主权限已转移给 ${room.players[0].name}`);
        }
        
        // 获取房主信息
        const host = room.players.find(p => p.id === room.hostId);
        const isGameEnded = room.gameState && room.gameState.isGameEnded;
        
        // 通知房间内剩余的玩家（为每个玩家单独发送isHost）
        room.players.forEach(player => {
          const playerSocket = io.sockets.sockets.get(player.id);
          if (playerSocket) {
            const isHost = room.hostId === player.id;
            const message = hostChanged
              ? `房主 ${playerName} 已掉线，${host.name} 成为新房主。`
              : `玩家 ${playerName} 已掉线。`;
            playerSocket.emit('player_left', { 
              players: room.players,
              message: message,
              isGameStarted: room.currentGame && !isGameEnded,
              hostId: room.hostId,
              hostName: host ? host.name : '',
              isHost: isHost,
              hostChanged: hostChanged // 标记房主是否变更
            });
          }
        });

        // 如果房间没人了，就删除房间
        if (room.players.length === 0) {
          delete rooms[roomId];
          console.log(`房间 ${roomId} 已解散`);
        }
        
        break; // 一个玩家通常只在一个游戏房间里
      }
    }
  });
});

// ... (启动服务器) ...
const PORT = 3001;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});